// memory.h

// Copyright (C) 2010  traxex

// Author: 	traxex <traxex@yahoo.cn>
// Created: 	18 Apr 2010
// Version: 	1.0
#pragma once

namespace traxex{
namespace cuda{

template<typename T> T* dmalloc( uint size){
    void *ptr;
    _safecall( cudaMalloc ( &ptr, size*sizeof(T)));
    return (T*)ptr;
}
	
inline  void dfree( void *ptr){
    _safecall( cudaFree( ptr));
}

template<typename T> T* hmalloc ( uint size){
    void *ptr;
    _safecall( cudaHostAlloc( &ptr, size*sizeof(T), 0));
    return (T*)ptr;
}

inline void hfree( void *ptr){
    _safecall( cudaFreeHost( ptr));
}

template<typename T>struct HDmap{ T *h; T *d;};
template<typename T>HDmap<T> hdmalloc( uint size){
    HDmap<T> hd;
    _safecall( cudaHostAlloc( &hd.h, size*sizeof(T), cudaHostAllocMapped));
    _safecall( cudaHostGetDevicePointer( &hd.d, &hd.h, 0));
    return hd;
}

inline void hdfree( void *ptr){
    _safecall( cudaFreeHost( ptr));
}

template<typename T> void d2dcpy( T *dst, const T *src, uint size ){
    _safecall( cudaMemcpy( dst, src, size*sizeof(T), cudaMemcpyDeviceToDevice ) );
}

template<typename T> void d2hcpy( T *dst, const T *src, uint size ){
    _safecall( cudaMemcpy( dst, src, size*sizeof(T), cudaMemcpyDeviceToHost ) );
}

template<typename T> void h2dcpy( T *dst, const T *src, uint size ){
    _safecall( cudaMemcpy( dst, src, size*sizeof(T), cudaMemcpyHostToDevice ) );
}

template<typename T> void h2hcpy( T *dst, const T *src, uint size ){
    _safecall( cudaMemcpy( dst, src, size*sizeof(T), cudaMemcpyHostToHost ) );
}


template<typename T> void a_d2dcpy( T *dst, const T *src, uint size, cudaStream_t stream=0 ){
    _safecall( cudaMemcpyAsync( dst, src, size*sizeof(T), cudaMemcpyDeviceToDevice , stream ) );
}

template<typename T> void a_d2hcpy( T *dst, const T *src, uint size, cudaStream_t stream=0 ){
    _safecall( cudaMemcpyAsync( dst, src, size*sizeof(T), cudaMemcpyDeviceToHost , stream ) );
}

template<typename T> void a_h2dcpy( T *dst, const T *src, uint size, cudaStream_t stream=0 ){
    _safecall( cudaMemcpyAsync( dst, src, size*sizeof(T), cudaMemcpyHostToDevice , stream ) );
}

template<typename T> void a_h2hcpy( T *dst, const T *src, uint size, cudaStream_t stream=0 ){
    _safecall( cudaMemcpyAsync( dst, src, size*sizeof(T), cudaMemcpyHostToHost , stream ) );
}
}
}

